package com.xiyu.service.service.fee;

import com.xiyu.service.vo.fee.feeRecharge.FeeRechargeSingleGetByElderIdOutput;
import com.xiyu.service.enums.fee.recharge.FeeRechargeDetailStatusEnum;
import com.xiyu.service.model.fee.recharge.FeeRechargeDetailDraft;
import com.xiyu.service.vo.fee.feeRecharge.FeeRechargeCreateInput;
import com.xiyu.service.model.fee.recharge.FeeRechargeFlow;
import com.xiyu.service.repository.fee.recharge.FeeRechargeFlowRepository;
import com.xiyu.service.vo.fee.feeRecharge.FeeRechargePageQueryFlowOutput;
import com.xiyu.service.vo.fee.feeRecharge.FeeRechargePageQueryFlowInput;
import com.xiyu.service.model.fee.recharge.FeeRechargeDetail;
import com.xiyu.service.repository.fee.recharge.FeeRechargeDetailRepository;
import com.xiyu.service.vo.fee.feeRecharge.FeeRechargePageQueryDetailOutput;
import com.xiyu.service.vo.fee.feeRecharge.FeeRechargePageQueryDetailInput;
import com.xiyu.service.model.fee.recharge.FeeRecharge;
import com.xiyu.service.repository.fee.recharge.FeeRechargeRepository;
import com.xiyu.service.vo.fee.feeRecharge.FeeRechargePageQueryOutput;
import com.xiyu.service.vo.fee.feeRecharge.FeeRechargePageQueryInput;
import org.springframework.stereotype.Service;
import jakarta.annotation.Resource;
import org.springframework.validation.annotation.Validated;
import org.babyfish.jimmer.Page;
import java.util.*;

import org.springframework.transaction.annotation.Transactional;
import com.xiyu.service.framework.web.web.core.pojo.PageResult;
import com.xiyu.service.convert.fee.FeeRechargeConvert;

import static com.xiyu.service.framework.exception.util.ServiceExceptionUtil.exception;
import static com.xiyu.service.errorCode.fee.FeeRechargeErrorCode.*;

/**
 * 预充值费用管理 Service 实现类
 */
@Service
@Validated
public class FeeRechargeServiceImpl implements FeeRechargeService {

    @Resource
    private FeeRechargeFlowRepository feeRechargeFlowRepository;

    @Resource
    private FeeRechargeDetailRepository feeRechargeDetailRepository;

    @Resource
    private FeeRechargeRepository feeRechargeRepository;

    @Override
    public PageResult<FeeRechargePageQueryOutput> pageQuery(FeeRechargePageQueryInput inputVO) {
        Page<FeeRecharge> pageFeeRecharge = feeRechargeRepository.pageQuery(inputVO);
        List<FeeRechargePageQueryOutput> listFeeRecharge = FeeRechargeConvert.INSTANCE.pageQueryOutputConvert(pageFeeRecharge.getRows());
        return new PageResult<>(listFeeRecharge, pageFeeRecharge.getTotalRowCount());
    }

    @Override
    public PageResult<FeeRechargePageQueryDetailOutput> pageQueryDetail(FeeRechargePageQueryDetailInput inputVO) {
        Page<FeeRechargeDetail> pageFeeRechargeDetail = feeRechargeDetailRepository.pageQueryDetail(inputVO);
        List<FeeRechargePageQueryDetailOutput> listFeeRechargeDetail = FeeRechargeConvert.INSTANCE.pageQueryDetailOutputConvert(pageFeeRechargeDetail.getRows());
        return new PageResult<>(listFeeRechargeDetail, pageFeeRechargeDetail.getTotalRowCount());
    }

    @Override
    public PageResult<FeeRechargePageQueryFlowOutput> pageQueryFlow(FeeRechargePageQueryFlowInput inputVO) {
        Page<FeeRechargeFlow> pageFeeRechargeFlow = feeRechargeFlowRepository.pageQueryFlow(inputVO);
        List<FeeRechargePageQueryFlowOutput> listFeeRechargeFlow = FeeRechargeConvert.INSTANCE.pageQueryFlowOutputConvert(pageFeeRechargeFlow.getRows());
        return new PageResult<>(listFeeRechargeFlow, pageFeeRechargeFlow.getTotalRowCount());
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Long create(FeeRechargeCreateInput inputVO) {
        FeeRechargeDetail newFeeRechargeDetail = FeeRechargeConvert.INSTANCE.createInputConvert(inputVO);
        newFeeRechargeDetail = feeRechargeDetailRepository.insert(newFeeRechargeDetail);
        return newFeeRechargeDetail.id();

    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean confirm(Long id) {
        Optional<FeeRechargeDetail> optionalFeeRechargeDetail = feeRechargeDetailRepository.findById(id);
        if(!optionalFeeRechargeDetail.isPresent()){
            throw exception(FEE_RECHARGE_DETAIL_NOT_EXISTS);
        }
        FeeRechargeDetail feeRechargeDetail = FeeRechargeDetailDraft.$.produce(optionalFeeRechargeDetail.get(), draft -> {
           draft.setStatus(FeeRechargeDetailStatusEnum.PAID_FULL.getValue());
        });
        feeRechargeDetailRepository.update(feeRechargeDetail);
        return true;
    }

    @Override
    public FeeRechargeSingleGetByElderIdOutput singleGetByElderId(Long id) {
        Optional<FeeRecharge> optionFeeRecharge = feeRechargeRepository.findByElderId(id);
        if(!optionFeeRecharge.isPresent()){
            throw exception(FEE_RECHARGE_NOT_EXIST);
        }
        return FeeRechargeConvert.INSTANCE.singleGetByElderIdOutputConvert(optionFeeRecharge.get());

    }

}
